package main.java.DMDE.view;

import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;

import javax.swing.AbstractButton;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JScrollPane;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;

import com.jgoodies.forms.factories.CC;
import com.jgoodies.forms.layout.FormLayout;

import main.java.DMDE.controllers.IRelationshipController;
import main.java.DMDE.controllers.RelationshipController;
import main.java.DMDE.infrastructure.visual.AttributeTreeNode;
import main.java.DMDE.infrastructure.visual.OperationNode;
import main.java.DMDE.infrastructure.visual.RelationshipNode;
import main.java.DMDE.model.Attribute;
import main.java.DMDE.model.CardinalityValues;
import main.java.DMDE.model.Entity;
import main.java.DMDE.model.Method;
import main.java.DMDE.model.Modifier;
import main.java.DMDE.model.Visibility;
import main.java.DMDE.model.relationships.Relationship;
import main.java.DMDE.model.relationships.RelationshipComponent;
import main.java.DMDE.model.relationships.RelationshipTypes;

public class RelationshipView implements IRelationshipView {

    private IRelationshipController relatController;
    private static String TITLE = "Relationship Creation";

    private JFrame frame;
    private JList<RelationshipNode> relatModelList;
    private DefaultListModel<RelationshipNode> relatModel; 
    private Relationship relationshipSelected;
    private JButton createButton, add, edit, remove;
    private List<Relationship> relationships;
    private JComboBox<String> relationshipTypeComboBox;
    private JLabel relationshipTypeText,labelEntityA,labelEntityB;
    private JScrollPane scrollPane;
    private RelationshipEntityView relationEntityA, relationEntityB;
    private JButton clean;
    
    public RelationshipView(){
	
	this.relationships = new ArrayList<Relationship>();
	initComponents();
	initList();
	
	relationshipTypeComboBox.addActionListener(new ActionListener() {
	    @Override
	    public void actionPerformed(ActionEvent actionEvent) {
//		relationEntityA.initialize();
//		relationEntityB.initialize();
		RelationshipTypes selectedType = (RelationshipTypes) relationshipTypeComboBox.getSelectedItem();
		if(selectedType != null && selectedType.getDescription() != " "){
		    	if(selectedType.equals(RelationshipTypes.Inheritance)){
			    relationEntityA.diableCardinality();
			    relationEntityB.diableCardinality();
			} 
			relatController.createRelationship(selectedType.getDescription());
			List<String> entitiesA = relatController.getEntitiesA();
			relationEntityA.setEntities(entitiesA);
	 	}	
	    }
	});

	relationEntityA.addActionListener(new ActionListener() {
	    @Override
	    public void actionPerformed(ActionEvent actionEvent) {
		String entityAName = relationEntityA.getSelectedEntity();
		if(entityAName != " "){
			List<String> entitiesB = relatController.getEntitiesB(entityAName);
			relationEntityB.setEntities(entitiesB);
	 	}	
	    }
	});
	
	add.addActionListener(new ActionListener() {
	    @Override
	    public void actionPerformed(ActionEvent actionEvent) {
		addRelationship();
	    }
	});
	
	edit.addActionListener(new ActionListener() {
	    @Override
	    public void actionPerformed(ActionEvent actionEvent) {
		editRelationship();
	    }
	});
	
	remove.addActionListener(new ActionListener() {
	    @Override
	    public void actionPerformed(ActionEvent actionEvent) {
		removeRelationship();
	    }
	});
	
	clean.addActionListener(new ActionListener() {
	    @Override
	    public void actionPerformed(ActionEvent actionEvent) {
		clean();
	    }
	});
	
	createButton.addActionListener(new ActionListener() {
	    @Override
	    public void actionPerformed(ActionEvent actionEvent) {
		try {
		    createRelationships();
		} catch (Exception e) {
		    // TODO Auto-generated catch block
		    e.printStackTrace();
		}
	    }
	});
	
    }

    private void addRelationship() {
	Relationship relationshipCreated = relatController.addRelationship();
	if (relationshipCreated != null) {
	    relatModel.addElement(new RelationshipNode(relationshipCreated));
	    setDefault();
	}
	
    }
    
    private void editRelationship() {
	if (relationshipSelected != null) {
	    if (this.relatController.editRelationship(relationshipSelected)) {
		relationshipSelected = null;
		clean();
	    }
	}    
    }
   
    private void removeRelationship() {
	if (relationshipSelected != null) {
	    if (this.relatController.removeRelationship(relationshipSelected)) {
		RelationshipNode node = relatModelList.getSelectedValue();
		relatModel.removeElement(node);
		relationshipSelected = null;
		setDefault();
	    }
	}
    }
    
    private void clean() {
	relationshipTypeComboBox.setEnabled(true);
	setDefault();
	relatModelList.clearSelection();
    }
    
    @SuppressWarnings({ "unchecked", "rawtypes" })
    private void initComponents() {
	
	frame = new JFrame();
	createButton = new JButton();
	frame.setTitle(TITLE);
	Container frameContentPane = frame.getContentPane();
	frameContentPane.setLayout(new FormLayout(
		"4dlu,90dlu,8dlu,pref,4dlu,pref,4dlu,pref,4dlu,pref,10dlu",
		"4dlu,pref,15dlu,pref,15dlu,pref,15dlu,pref,15dlu,pref,15dlu,pref,15dlu,pref,fill:10dlu:grow"));

	scrollPane = new JScrollPane();
	frameContentPane.add(scrollPane, CC.xywh(2, 2, 1, 10));

	relationshipTypeText = new JLabel();
	relationshipTypeComboBox = new JComboBox(RelationshipTypes.values());
	relationshipTypeText.setText("Type");
	relationshipTypeText.setLabelFor(relationshipTypeComboBox);
	frameContentPane.add(relationshipTypeText, CC.xy(4, 2));
	frameContentPane.add(relationshipTypeComboBox, CC.xy(6,2));

	labelEntityA = new JLabel();
	labelEntityA.setText("Entity A: ");
	labelEntityB = new JLabel();
	labelEntityB.setText("Entity B: ");
	frameContentPane.add(labelEntityA,CC.xy(4,4));
	frameContentPane.add(labelEntityB,CC.xy(8,4));
	
	
	relationEntityA = new RelationshipEntityView();
	relationEntityB = new RelationshipEntityView();
	relationEntityA.addLabels(frameContentPane,4,6);
	relationEntityB.addLabels(frameContentPane,8,6);
	this.setDefault();
	
	add = new JButton("Add");
	edit = new JButton("Edit");
	remove = new JButton("Remove");
	frameContentPane.add(add, CC.xy(6, 12));
	frameContentPane.add(edit, CC.xy(8, 12));
	frameContentPane.add(remove, CC.xy(10, 12));
			
	this.initList();
	createButton.setText("Finish");
	frameContentPane.add(createButton, CC.xy(10,14));
	clean = new JButton("Clean");
	frameContentPane.add(clean, CC.xy(8,14));
	frame.pack();
	frame.setLocationRelativeTo(frame.getOwner());
	
    }
    
    private void initList(){
	
	this.relatModelList = new JList<RelationshipNode>();
	scrollPane.setViewportView(relatModelList);
	relatModel = new DefaultListModel<RelationshipNode>();
	relatModelList.setModel(relatModel);
	this.relationshipSelected = null;
	relatModelList.addListSelectionListener(new ListSelectionListener() {

	    @Override
	    public void valueChanged(ListSelectionEvent e) {
		if (!e.getValueIsAdjusting()) {
		    if (relatModelList.getSelectedValue() instanceof RelationshipNode) {
			Relationship relationshipSelected = ((RelationshipNode)relatModelList.getSelectedValue()).getRelationship();
			relationshipSelected(relationshipSelected);
			relationshipTypeComboBox.setEnabled(false);
		    } else {
			relationshipSelected = null;
		    }
		}
	    }
	});
    }

    @Override
    public List<Relationship> getRelationships() {
	loadRelationship();
	return relationships;
    }
    
    @Override
    public void loadRelationship() {
	for (int i = 0; i < relatModel.getSize(); i++) {
	    relationships.add(relatModel.getElementAt(i).getRelationship());
	}
    }
    
    private void setDefault(){
	relationshipTypeComboBox.setSelectedIndex(-1);
	cleanEntities();

    }
    
    private void relationshipSelected(Relationship relationshipSelected) {
	if (relationshipSelected != null) {
	    this.relationshipSelected = relationshipSelected;
	    System.out.println(relationshipSelected);
	    this.relationshipTypeComboBox.setSelectedItem(relationshipSelected.getType());
	    this.relationEntityA.selectValue(relationshipSelected.getComponentA());
	    this.relationEntityB.selectValue(relationshipSelected.getComponentB());
	}	
    }
    
    @Override
    public void setController(RelationshipController relationshipController) {
	this.relatController = relationshipController;
    }

    private void createRelationships() throws Exception {
 	relatController.addRelationshipsToDiagram();
 	    this.frame.setVisible(false);
// 	} else {
 //	    showWrongClassNameDialog();
 //	}

     }
    
    @Override
    public void show() {
	this.frame.setVisible(true);	
    }


    @Override
    public void cleanEntities() {
	relationEntityA.initialize();
	relationEntityA.setDefault();
	relationEntityB.initialize();
	relationEntityB.setDefault();
    }


    @Override
    public CardinalityValues getMinEntityB() {
	return relationEntityB.getMin();
    }

    @Override
    public CardinalityValues getMaxEntityB() {
	return relationEntityB.getMax();
    }

    @Override
    public CardinalityValues getMinEntityA() {
	return relationEntityA.getMin();
    }


    @Override
    public CardinalityValues getMaxEntityA() {
	return relationEntityA.getMax();
    }

    @Override
    public String getEntityNameA() {
	return relationEntityA.getSelectedEntity();
    }


    @Override
    public String getEntityNameB() {
	return relationEntityB.getSelectedEntity();
    }

    @Override
    public void setType(RelationshipTypes type) {
	this.relationshipTypeComboBox.setSelectedItem(type);
	
    }

    @Override
    public void setComponents(RelationshipComponent compA,
	    RelationshipComponent compB) {
	this.relationEntityA.selectValue(compA);
	this.relationEntityB.selectValue(compB);
    }

    @Override
    public void setRelationship(Relationship relationship) {
	relatModel.addElement(new RelationshipNode(relationship));
    }


}
